package com.orangelife.service.propFeePollfee.impl;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Pattern;

import javax.annotation.Resource;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.springframework.stereotype.Service;

import com.orangelife.exception.AppBizException;
import com.orangelife.service.Importlogs.QiniuUtils;
import com.orangelife.service.propFeeCommInfo.IPropFeeCommInfoService;
import com.orangelife.service.propFeeComputeRule.IPropFeeComputeRuleService;
import com.orangelife.service.propFeeComputeRule.model.PropFeeComputeRuleDto;
import com.orangelife.service.propFeePollfee.IImportPollFeeService;
import com.orangelife.service.propFeePollfee.IPropFeePollfeeService;
import com.orangelife.service.propFeePollfee.model.PropFeePollfeeDto;
import com.orangelife.service.propFeePollfeeImportLog.IPropFeePollfeeImportLogService;
import com.orangelife.service.propFeePollfeeImportLog.model.PropFeePollfeeImportLogDto;
import com.orangelife.utils.IdUtil;
import com.orangelife.utils.ListSetUtils;
import com.orangelife.utils.PropertyUtils;
import com.orangelife.utils.StringUtils;

@Service("importPollFeeService")
public class ImportPollFeeServiceImpl implements IImportPollFeeService {
	@Resource(name = "propFeePollfeeService")
	private IPropFeePollfeeService propFeePollfeeService;

	@Resource(name = "propFeeComputeRuleService")
	private IPropFeeComputeRuleService propFeeComputeRuleService;
	@Resource(name = "propFeeCommInfoService")
	private IPropFeeCommInfoService propFeeCommInfoService;

	private QiniuUtils qiniuUtils = new QiniuUtils();

	@Resource(name = "propFeePollfeeImportLogService")
	private IPropFeePollfeeImportLogService propFeePollfeeImportLogService;

	@Override
	public int importPollFee(Sheet sheet, String commID, String fileName)
			throws AppBizException {
		PropFeePollfeeImportLogDto cmmImportLog = new PropFeePollfeeImportLogDto();
		Map<Integer, String> logmap = new TreeMap<Integer, String>();
		int rowCount = sheet.getPhysicalNumberOfRows();// 获得总行数
		if (rowCount < 1) {
			throw new AppBizException(2, "sheet页无数据");
		}

		/****
		 * 添加失败日志
		 */

		cmmImportLog.setCreateuserID("1");
		cmmImportLog.setImportLogID(IdUtil.getuuId());
		cmmImportLog.setItemStat("1");
		cmmImportLog.setStatus("1");
		cmmImportLog.setTscreate(new Date());
		cmmImportLog.setTsedit(new Date());
		cmmImportLog.setFileName(fileName);
		propFeePollfeeImportLogService.addPropFeePollfeeImportLog(cmmImportLog);

		Row row = sheet.getRow(0);// 第一行
		int columnCount = row.getLastCellNum();// 获取列数
		Map<String, Integer> columnMap = new HashMap<String, Integer>();
		for (int i = 0; i < columnCount; i++) {
			String columnName = row.getCell((short) i).getStringCellValue()
					.trim();
			if (columnName.equals("规则ID")) {
				columnMap.put("规则ID", i);
			}

			if (columnName.equals("类目名称")) {
				columnMap.put("类目名称", i);
			}
			if (columnName.equals("房屋ID")) {
				columnMap.put("房屋ID", i);
			}
			if (columnName.equals("房屋类型")) {
				columnMap.put("房屋类型", i);
			}
			if (columnName.equals("楼栋")) {
				columnMap.put("楼栋", i);
			}

			if (columnName.equals("单元")) {
				columnMap.put("单元", i);
			}
			if (columnName.equals("房号")) {
				columnMap.put("房号", i);
			}
			if (columnName.equals("期数")) {
				columnMap.put("期数", i);
			}
			if (columnName.equals("本期金额")) {
				columnMap.put("本期金额", i);
			}

		}

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("commID", commID);

		List<Map<String, Object>> propFeePollfees = PropertyUtils
				.turnToEntity(propFeePollfeeService.findPropFeePollfee(commID,
						null, null, null));
		try {
			checkRecordColum(columnMap, commID, cmmImportLog,logmap);

		} catch (Exception e) {
			return 0;
		}

		Set<PropFeePollfeeDto> recordDtos = notNull(sheet, rowCount, columnMap,
				propFeePollfees, commID, cmmImportLog, logmap);
		ListSetUtils listSetUtils = new ListSetUtils();
		List<List<PropFeePollfeeDto>> li = listSetUtils.splitList(
				listSetUtils.setToList(recordDtos), 200);
		for (int i = 0; i < li.size(); i++) {
			HandlePollFeeThread thread = new HandlePollFeeThread("线程[" + (i)
					+ "] ", li.get(i), propFeePollfeeService);
			thread.start();
		}
		return columnCount;

	}

	public Set<PropFeePollfeeDto> notNull(Sheet sheet, int rowCount,
			Map<String, Integer> columnMap,
			List<Map<String, Object>> propFeePollfees, String commID,
			PropFeePollfeeImportLogDto cmmImportLog, Map<Integer, String> logmap)
			throws AppBizException {
		int errortol = 0;
		int total = 0;
		Set<PropFeePollfeeDto> propFeePollfeeDto = new HashSet<PropFeePollfeeDto>();
		Row firstRow = sheet.getRow(1);
		if (firstRow == null) {
			throw new AppBizException(99, "亲，请最少填写一行信息");
		}

		for (int i = 1; i < rowCount; i++) {
			try {

				PropFeePollfeeDto propFeePollfee = new PropFeePollfeeDto();

				Row dataRow = sheet.getRow(i);
				if (dataRow == null) {
					break;
				}

				if (2 == (getCellInfoByHouseInfo(i + 1, dataRow, columnMap,
						logmap, propFeePollfees, propFeePollfeeDto))) {
					errortol++;
					continue;
				} else if (1 == (getCellInfoByHouseInfo(i + 1, dataRow,
						columnMap, logmap, propFeePollfees, propFeePollfeeDto))) {
					logmap.put(i + 1, "该行出现了的空行，导入停止");
					break;

				} else if (3 == (getCellInfoByHouseInfo(i + 1, dataRow,
						columnMap, logmap, propFeePollfees, propFeePollfeeDto))) {
					// logmap.put(j + 1, "该行出现了的空行，导入停止");
					break;

				}

				propFeePollfee.setRuleID(this.getCellValue(dataRow
						.getCell(columnMap.get("规则ID"))));

				propFeePollfee.setApartmentID(this.getCellValue(dataRow
						.getCell(columnMap.get("房屋ID"))));

				propFeePollfee.setAmount(new BigDecimal(this.getCellValue(dataRow.getCell(columnMap
						.get("本期金额")),"0.##")));

				propFeePollfee.setRowNum(String.valueOf(i));

				PropFeeComputeRuleDto propFeeComputeRuleDto = propFeeComputeRuleService
						.findPropFeeComputeRuleByID(propFeePollfee.getRuleID());
				if (propFeeComputeRuleDto != null) {
					propFeePollfee.setCommID(propFeeComputeRuleDto.getCommID());
				propFeePollfee.setLinkID(propFeeComputeRuleDto.getInitID());
					/*
					 * Map<String, String> nextTime = propFeeCommInfoService
					 * .findLastDate(propFeeComputeRuleDto.getCommID()); if
					 * (nextTime == null || nextTime.size() < 0) { throw new
					 * AppBizException(2, "亲小区期数"); }
					 */
					// propFeePollfee.setPeriod(nextTime.get("nextTime"));
				}

				propFeePollfee.setStatus("0");
				propFeePollfeeDto.add(propFeePollfee);
				total++;
			} catch (Exception e) {
				e.printStackTrace();
				logmap.put(i + 1, "行数据转换错误,错误原因：" + e.getMessage());
				errortol++;
			}
		}
		cmmImportLog.setStatus("2");
		cmmImportLog.setImportInfo("成功" + total + "条" + ",失败" + errortol + "条");
		String logurl = qiniuUtils.createErrorLogFile(logmap);
		cmmImportLog.setLink(logurl);

		cmmImportLog.setFinishTime(new Date(new Date().getTime() + 1000 * total
				* 4));
		cmmImportLog.setTsedit(new Date());
		cmmImportLog.setCommID(commID);
		propFeePollfeeImportLogService
				.editPropFeePollfeeImportLog(cmmImportLog);
		return propFeePollfeeDto;

	}

	public void checkRecordColum(Map<String, Integer> map, String commID,
			PropFeePollfeeImportLogDto cmmImportLog, Map<Integer, String> logmap)
			throws AppBizException {

		// String info = "规则ID,类目名称,房屋ID,房屋类型,房屋信息,期数, 本期金额";

		try {
			if (map == null || map.size() <= 0) {
				throw new AppBizException(99, "亲,使用正确的excel的格式");
			}

			if (!map.containsKey("规则ID")) {
				throw new AppBizException(99, "亲,使用正确的excel的格式(缺少规则ID)");
			}
			if (!map.containsKey("类目名称")) {
				throw new AppBizException(99, "亲,使用正确的excel的格式(缺少类目名称)");
			}
			if (!map.containsKey("房屋ID")) {
				throw new AppBizException(99, "亲,使用正确的excel的格式(缺少房屋ID)");
			}
			if (!map.containsKey("房屋类型")) {
				throw new AppBizException(99, "亲,使用正确的excel的格式(缺少房屋类型)");
			}

			if (!map.containsKey("楼栋")) {
				throw new AppBizException(99, "亲,使用正确的excel的格式(缺少楼栋)");
			}
			if (!map.containsKey("单元")) {
				throw new AppBizException(99, "亲,使用正确的excel的格式(缺少单元)");
			}
			if (!map.containsKey("房号")) {
				throw new AppBizException(99, "亲,使用正确的excel的格式(缺少房号)");
			}

			if (!map.containsKey("期数")) {
				throw new AppBizException(99, "亲,使用正确的excel的格式(缺少期数)");
			}
			if (!map.containsKey("本期金额")) {
				throw new AppBizException(99, "亲,使用正确的excel的格式(缺少本期金额)");
			}
		} catch (Exception e) {
			logmap.put(1, e.getMessage());
			/****
			 * 添加失败日志
			 */
			cmmImportLog.setStatus("3");
			cmmImportLog.setImportInfo("成功0条");
			String logurl = qiniuUtils.createErrorLogFile(logmap);
			cmmImportLog.setLink(logurl);
			cmmImportLog.setFinishTime(new Date());
			cmmImportLog.setTsedit(new Date());
			cmmImportLog.setCommID(commID);
			propFeePollfeeImportLogService
					.editPropFeePollfeeImportLog(cmmImportLog);
			throw new AppBizException(99, e.getMessage());
		}

	}

	public int getCellInfoByHouseInfo(int rownum, Row dataRow,
			Map<String, Integer> columnMap, Map<Integer, String> logmap,
			List<Map<String, Object>> houseInfos,
			Set<PropFeePollfeeDto> propFeePollfeeDtos) throws AppBizException {

		/***
		 * 跳过空白行
		 */
		if (StringUtils.isBlank(this.getCellValue(dataRow.getCell(columnMap
				.get("规则ID"))))
				&& StringUtils.isBlank(this.getCellValue(dataRow
						.getCell(columnMap.get("类目名称"))))
				&& StringUtils.isBlank(this.getCellValue(dataRow
						.getCell(columnMap.get("房屋ID"))))
				&& StringUtils.isBlank(this.getCellValue(dataRow
						.getCell(columnMap.get("房屋类型"))))
				&& StringUtils.isBlank(this.getCellValue(dataRow
						.getCell(columnMap.get("楼栋"))))
				&& StringUtils.isBlank(this.getCellValue(dataRow
						.getCell(columnMap.get("房号"))))
				&& StringUtils.isBlank(this.getCellValue(dataRow
						.getCell(columnMap.get("期数"))))
				&& StringUtils.isBlank(this.getCellValue(dataRow
						.getCell(columnMap.get("本期金额"))))) {
			return 1;

		}

		if (StringUtils.isBlank(this.getCellValue(dataRow.getCell(columnMap
				.get("规则ID"))))) {
			logmap.put(rownum, "亲，第" + rownum + "行规则ID为空");
			return 2;
			// throw new AppBizException(2, "亲，第" + i + "行楼栋为空");
		}
		if (StringUtils.isBlank(this.getCellValue(dataRow.getCell(columnMap
				.get("房屋ID"))))) {
			// throw new AppBizException(2, "亲，第" + i + "行房号为空");
			logmap.put(rownum, "亲，第" + rownum + "行房屋ID为空");
			return 2;
		}
		if (StringUtils.isBlank(this.getCellValue(dataRow.getCell(columnMap
				.get("本期金额")),"0.##"))) {
			// throw new AppBizException(2, "亲，第" + i + "行 是否预缴为空");
			logmap.put(rownum, "亲，第" + rownum + "行是本期金额为空");
			return 2;
		}
		if (!this.getDouble(this.getCellValue(dataRow.getCell(columnMap
				.get("本期金额")),"0.##"))) {
			logmap.put(rownum, "亲，第" + rownum + "行本期金额错误（正确格式 为数字）");
			return 2;
		}
		boolean isCheck = false;
		String apartmentID = this.getCellValue(dataRow.getCell(columnMap
				.get("房屋ID")));
		String ruleID = this
				.getCellValue(dataRow.getCell(columnMap.get("规则ID")));
		for (Map<String, Object> house : houseInfos) {
			if (ruleID.equals(house.get("ruleID").toString())
					&& apartmentID.equals(house.get("apartmentID")))
				isCheck = true;
		}
		if (!isCheck) {
			logmap.put(rownum, "亲，第" + rownum + "行 规则信息与房屋信息不属于该小区");
			return 2;
		}

		if (propFeePollfeeDtos != null && propFeePollfeeDtos.size() > 0) {
			boolean isExIst = false;
			String row = "";
			for (PropFeePollfeeDto propFeePollfeeDto : propFeePollfeeDtos) {
				if (propFeePollfeeDto.getRuleID().equals(ruleID)
						&& propFeePollfeeDto.getApartmentID().equals(
								apartmentID)) {
					isExIst = true;
					row = propFeePollfeeDto.getRowNum();
					break;
				}
			}
			if (isExIst) {
				logmap.put(rownum, "亲，第" + rownum + "行相关信息与" + row + "行信息重复");
				return 2;
			}

		}
		return 0;
	}

	public String getCellValue(Cell cell) throws AppBizException {
		String cellValue = null;
		try {
			if (cell != null) {
				switch (cell.getCellType()) {
				case Cell.CELL_TYPE_NUMERIC: {
					if (DateUtil.isCellDateFormatted(cell)) {
						Date date = cell.getDateCellValue();
						SimpleDateFormat format = new SimpleDateFormat(
								"yyyy-MM-dd HH:mm:ss");
						cellValue = format.format(date);

					} else {
						DecimalFormat df = new DecimalFormat("#");
						cellValue = df.format(cell.getNumericCellValue());

					}
				}
					break;
				case Cell.CELL_TYPE_STRING: {
					cellValue = cell.getStringCellValue().trim();
				}
					break;

				default:
					break;
				}
			}
		} catch (Exception e) {
			throw new AppBizException(99, e.getMessage());
		}
		return cellValue;
	}

	public boolean getDouble(String str) {
		if (StringUtils.isBlank(str)) {
			return false;
		}
		if (str.contains(".")) {
			Pattern pattern = Pattern.compile("[-+]?[0-9]+(\\.[0-9]+)?");

			// System.out.println(pattern.matcher(str).matches());

			return pattern.matcher(str).matches();
		} else {
			return str.matches("^[0-9_]+$");
		}
	}
	private String getCellValue(Cell cell, String format1)
			throws AppBizException {
		String cellValue = null;
		try {
			if (cell != null) {
				switch (cell.getCellType()) {
				case Cell.CELL_TYPE_NUMERIC: {
					if (DateUtil.isCellDateFormatted(cell)) {
						Date date = cell.getDateCellValue();
						SimpleDateFormat format = new SimpleDateFormat(
								"yyyy-MM-dd HH:mm:ss");
						cellValue = format.format(date);

					} else {
						DecimalFormat df = new DecimalFormat(
								format1 == null ? "#" : format1);
						cellValue = df.format(cell.getNumericCellValue());
						// cellValue = String.valueOf((int) cell
						// .getNumericCellValue());
					}
				}
					break;
				case Cell.CELL_TYPE_STRING: {
					cellValue = cell.getStringCellValue().trim();
				}
					break;

				default:
					break;
				}
			}
		} catch (Exception e) {
			throw new AppBizException(99, e.getMessage());
		}
		return cellValue;
	}
}
